Customizing the Shipment Provider

A Shipping Provider is a pluggable component integrated into Ektron's Ektron CMS400.NET eCommerce module. The Shipping provider handles eCommerce real-time shipping rate retrieval by utilizing third party shipping services such as FedEx or UPS, or you can create your own fixed rate logic. Ektron CMS400.NET's eCommerce shipping module calculates the package(s) needed for an order and then passes the following information to the company providing the shipping services via a Shipping Provider.

package information - for example, how many, height, width, depth and weight of each package.

warehouse address - the address from which the items will be shipped. A warehouse’s information can be set in the Workarea > Settings > Commerce > Shipping > Warehouses screen.

destination address - the address a customer entered as his shipping address when making the purchase.

desired shipping options - for example, if you have Next Day, 2-Day Ground and 3-Day Ground as shipping options, you can pass the option chosen by the customer.

Ektron CMS400.NET comes with several shipping providers, including FedEx and UPS. You can customize these providers or create your own using the extendable Shipping Provider architecture.

Note: Your company will need to set up or have an existing account with a third party shipping service before utilizing the shipping provider. This includes shipping providers such as, FedEx or UPS, which are included with Ektron CMS400.NET's eCommerce Module.

Each type of shipping provider accepts configuration parameters. For example, FedEx requires a username, password, account number, and meter number while UPS requires a Username, password, and account number. These configuration parameters along with the provider definitions are stored in the SiteRoot/shipment.config file. Below is a provider definition example for FedEx.

<add name="FedExShipmentProvider" type="Ektron.Cms.Commerce.Providers.Shipment.FedExShipmentProvider, Ektron.Cms.Commerce.Providers" serviceUrl="https://gatewaybeta.fedex.com/web-services" key="" password="" accountNumber="" meterNumber="" transactionId="Ektron FedEx v3 

The following steps show the flow of shipping calculations for a customer purchasing a product from your site.

1. A customer adds two books his to cart and clicks checkout.

2. The shipping calculator looks for the smallest possible package that will fit the items.

3. The shipping calculator calls the registered shipping provider for each package in the order.

4. The shipping calculator combines all the rates received if more than one package is being shipped and returns the shipping method rates to the checkout control.

5. The customer selects the desired shipping method and it is saved with the cart.

Note: Many Ektron CMS400.NET settings affect your shipping calculations. A default warehouse must be defined with a valid shipping address. Shipping methods you would like to offer customers must be defined. For example, the FedEx provider supports over 10 possible shipping methods, but you may only be concerned with Priority, 2 Day, and Ground. This must be defined in Ektron CMS400.NET. You can also define the shipping packages your business uses. The Shipping calculator will try and fit the order items into any packages defined in the CMS. If no packages are defined, the item's dimensions are passed to the provider instead.

Shipment Provider Object Model

Below is the Object Model for Ektron’s Shipment Provider.

The ShipmentProvider is the abstract base class you must extend to implement your own Shipping Provider. Details and descriptions of the ShipmentProvider API can be found in the Ektron CMS400.NET API Reference Manual’s Providers API > Shipment > Provider > ShipmentProvider.

Creating a Custom Shipment Provider

In addition to the out-of-the-box shipment providers that come with Ektron CMS400.NET, you can create a custom provider that connects with any shipping company you choose. Below are the basic code steps you need to complete when creating a custom shipment provider. Additional code examples used by Ektron to create FedEx, Flat Rate and UPS shipment providers are located in: C:\Program Files\Ektron\CMS400SDK\Commerce\Providers\Commerce.Providers\Shipping

Note: The complete C# code sample used in this example is available at the end of this section. See CustomShipmentProvider Code Example

1. Create a class library project in Visual Studio.

2. Add references to these DLLs:

- Ektron.Cms.Commerce

- Ektron.Cms.Common

- Ektron.Cms.ObjectFactory

- Ektron.Cms.Instrumentation

- System.Configuration

3. Add these using statements to the code behind:

- using System.Configuration.Provider;

- using Ektron.Cms.Commerce.Shipment.Provider;

- using Ektron.Cms.Commerce;

- using Ektron.Cms.Instrumentation;

4. Change the namespace to:

namespace Ektron.Cms.Extensibility.Commerce.Samples

{

5. Rename your class and inherit as below:

public class CustomShipmentProvider : ShipmentPovider

{

6. Add the following constructor private variables and properties. The items added to the shippingOptionList are the shipping methods exposed as a service type in the management screen inside the Workarea.

                    

#region constructor, member variables

public CustomShipmentProvider()

{

IsTrackingSupported = false;

_shippingOptionList = new List<string>();

_shippingOptionList.Add("CustomOption_1");

_shippingOptionList.Add("CustomOption_2");

}

private List<string> _shippingOptionList;

#endregion

7. Add the following methods required by the ShipmentProvider base class.

                    

#region ShipmentProvider Implementation

public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)

{

if (config == null)

throw new ArgumentNullException("config");

// Assign the provider a default name if it doesn't have one

if (string.IsNullOrEmpty(name))

name = "CustomShipmentProvider";

if (string.IsNullOrEmpty(config["description"]))

{

config.Remove("description");

config.Add("description", "CustomShipmentProvider Provider");

}

// Call the base class's Initialize method

base.Initialize(name, config);

// Throw an exception if unrecognized attributes remain

if (config.Count == 0)

throw new ProviderException("Shipment provider attribute missing.");

else

{

//read all config attributes.

ServiceUrl = config["serviceUrl"];

Key = config["key"];

Password = config["password"];

AccountNumber = config["accountNumber"];

MeterNumber = config["meterNumber"];

TransactionId = config["transactionId"];

}

}

public override List<string> GetServiceTypes()

{

return _shippingOptionList;

}

public override string GetTrackingUrl(string trackingId)

{

return "";

}

public override List<ShippingOptionData> GetRates(IEnumerable<ShippingMethodData> expectedOptions, AddressData origin, AddressData destination, Weight weight, Dimensions dimensions)

{

}

#endregion

8. Implement the GetRates method. Add this code to public override for GetRates which was added during the previous step. When complete, the code should look like this.

Note: This example uses flat rates for your shipping methods. In a real world scenario, the shipping methods and their corresponding rates can be obtained via FedEx, UPS, a third party application or a Web service.

public override List<ShippingOptionData> GetRates(IEnumerable<ShippingMethodData> expectedOptions, AddressData origin, AddressData destination, Weight weight, Dimensions dimensions)

                    

{

List<ShippingOptionData> availableOptions = new List<ShippingOptionData>();

try

{

foreach (ShippingMethodData expectedOption in expectedOptions)

{

Log.WriteInfo("Custom Shipping Provider. ExpectedOption:" + expectedOption.Name);

switch (expectedOption.ProviderService.ToLower())

{

case "customoption_1":

ShippingOptionData customOption1 = new ShippingOptionData();

customOption1.Id = expectedOption.Id;

customOption1.Name = expectedOption.Name;

customOption1.ShippingFee = 25.00M;

customOption1.ProviderService = "CustomOption_1";

availableOptions.Add(customOption1);

break;

case "customoption_2":

ShippingOptionData customOption2 = new ShippingOptionData();

customOption2.Id = expectedOption.Id;

customOption2.Name = expectedOption.Name;

customOption2.ShippingFee = 50.00M;

customOption2.ProviderService = "CustomOption_2";

availableOptions.Add(customOption2);

break;

}

}

}

catch (Exception e)

{

Log.WriteError("Custom Shipping Provider: Error retrieving shipping rates." + e.Message);

throw;

}

return availableOptions;

}

}

}

Note: You can use the GetRates method to restrict countries to which you ship. For example, if you want to prevent shipping to all countries except Canada, add these lines of code to the GetRates method.

                    

if (destination.Country.Id != 124)

throw new Ektron.Cms.Commerce.Exceptions.Shipping.InvalidAddressException("We only ship to Canada.");

9. Save and build the project.

10. Copy your project’s DLL file to your Ektron Web site’s bin directory.

11. Register the provider in your site’s shipment.config file. This file provides the facility to manage shipping providers within Ektron CMS400.NET. Locate the shipmentProvider section and change the defaultProvider parameter to the name of your custom provider.

                    

<shipmentProvider defaultProvider="CustomShipmentProvider">

12. Add your custom shipping provider between the shipmentProvider’s <providers> tags. Note that the name defined here needs to match the name defined as the defaultProvider in the previous step.

                    

<providers>

<add name="CustomShipmentProvider" type="Ektron.Cms.Extensibility.Commerce.Samples.CustomShipmentProvider, CustomShipmentProvider" serviceUrl="" key="" password="" accountNumber="" meterNumber="" transactionId="CustomShipmentProvider based transaction" />

</providers>

13. Save the Web.config file.

Your custom shipping provider is now the default provider. Whenever you need to obtain shipping rate information, the information routes through the new custom provider.

14. Add the shipping methods that are available for your provider in the Workarea > Settings > Commerce -> Shipping > Methods screen.

  1. Select New > Shipping Method.
  2. Enter a name. This is what a customer sees during the checkout process. An example is “Ground” or “Next Day”. For this example, use “Custom1”.
  3. Check the Active checkbox.
  4. Click View Options and select CustomOption_1 from the list.
  5. Click Save ().
  6. Repeat this process for the CustomOption2 shipping method type.

The options are now available in the checkout process, and are shown on the shipping method selection screen.

CustomShipmentProvider Code Example

Warning! Copying and pasting the code below and using it without modification to create a DLL does not result in a working “real time” shipping provider. This example uses fixed rates and should be modified to meet your needs.

Below is the full C# code example used in this section. See Also: Creating a Custom Shipment Provider.

                    

using System.Configuration.Provider;

using Ektron.Cms.Commerce.Shipment.Provider;

using Ektron.Cms.Commerce;

using Ektron.Cms.Instrumentation;

namespace Ektron.Cms.Extensibility.Commerce.Samples

{

public class CustomShipmentProvider : ShipmentProvider

{

#region constructor, member variables

public CustomShipmentProvider()

{

IsTrackingSupported = false;

_shippingOptionList = new List<string>();

_shippingOptionList.Add("CustomOption_1");

_shippingOptionList.Add("CustomOption_2");

}

private List<string> _shippingOptionList;

#endregion

#region ShipmentProvider Implementation

public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)

{

if (config == null)

throw new ArgumentNullException("config");

// Assign the provider a default name if it doesn't have one

if (string.IsNullOrEmpty(name))

name = "CustomShipmentProvider";

if (string.IsNullOrEmpty(config["description"]))

{

config.Remove("description");

config.Add("description", "CustomShipmentProvider Provider");

}

// Call the base class's Initialize method

base.Initialize(name, config);

// Throw an exception if unrecognized attributes remain

if (config.Count == 0)

throw new ProviderException("Shipment provider attribute missing.");

else

{

//read all config attributes.

ServiceUrl = config["serviceUrl"];

Key = config["key"];

Password = config["password"];

AccountNumber = config["accountNumber"];

MeterNumber = config["meterNumber"];

TransactionId = config["transactionId"];

}

}

public override List<string> GetServiceTypes()

{

return _shippingOptionList;

}

public override string GetTrackingUrl(string trackingId)

{

return "";

}

public override List<ShippingOptionData> GetRates(IEnumerable<ShippingMethodData> expectedOptions, AddressData origin, AddressData destination, Weight weight, Dimensions dimensions)

{

List<ShippingOptionData> availableOptions = new List<ShippingOptionData>();

try

{

foreach (ShippingMethodData expectedOption in expectedOptions)

{

Log.WriteInfo("Custom Shipping Provider. ExpectedOption:" + expectedOption.Name);

switch (expectedOption.ProviderService.ToLower())

{

case "customoption_1":

ShippingOptionData customOption1 = new ShippingOptionData();

customOption1.Id = expectedOption.Id;

customOption1.Name = expectedOption.Name;

customOption1.ShippingFee = 25.00M;

customOption1.ProviderService = "CustomOption_1";

availableOptions.Add(customOption1);

break;

case "customoption_2":

ShippingOptionData customOption2 = new ShippingOptionData();

customOption2.Id = expectedOption.Id;

customOption2.Name = expectedOption.Name;

customOption2.ShippingFee = 50.00M;

customOption2.ProviderService = "CustomOption_2";

availableOptions.Add(customOption2);

break;

}

}

}

catch (Exception e)

{

Log.WriteError("Custom Shipping Provider: Error retrieving shipping rates." + e.Message);

throw;

}

return availableOptions;

}

#endregion

}

}

Previous TopicNext Topic|